package com.kevin.Code.Heap;

import java.util.*;

/**
 * @author Vinlee Xiao
 * @Classname TopkFrequentElements
 * @Description Leetcode 347 前K个高频元素 没思路 高频题
 * @Date 2021/11/19 14:06
 * @Version 1.0
 */
public class TopkFrequentElements {

    /**
     * 自己思路 快速排序 但是 效率低
     * 自己思路：HashMap 2 O(n)
     *
     * @param nums
     * @param k
     * @return
     */
    public int[] topKFrequent(int[] nums, int k) {

        int len = nums.length;

        HashMap<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < len; i++) {
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }

        List<int[]> list = new ArrayList<>();

        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Integer key = entry.getKey();
            Integer value = entry.getValue();
            list.add(new int[]{key, value});
        }

        //1.利用api

        Collections.sort(list, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return -Integer.compare(o1[1], o2[1]);
            }
        });

        int[] result = new int[k];

        for (int i = 0; i < k; i++) {
            result[i] = list.get(i)[0];
        }

        return result;
    }


    /**
     * 最小堆 堆排序官方题解提供的更好的思路
     *
     * @param nums
     * @param k
     * @return
     */
    public int[] topKFrequent1(int[] nums, int k) {

        int len = nums.length;

        HashMap<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < len; i++) {
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
        }


        //小根堆
        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1] - o2[1];
            }
        });

        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Integer value = entry.getValue();
            Integer key = entry.getKey();
            if (priorityQueue.size() == k) {

                //如果堆顶的元素小于当前元素则将当前元素插入
                if (priorityQueue.peek()[1] < value) {
                    //将堆顶的元素弹出堆中
                    priorityQueue.poll();
                    priorityQueue.add(new int[]{key, value});
                }

            } else {
                priorityQueue.add(new int[]{key, value});
            }
        }
        int[] result = new int[k];

        for (int i = 0; i < k; i++) {
            result[i] = priorityQueue.poll()[0];
        }


        return result;
    }


    /**
     * @param nums
     * @param k
     * @return
     */
    public int[] topKFrequent2(int[] nums, int k) {

        return new int[]{0};
    }

    public static void main(String[] args) {
        int[] nums = new int[]{1, 1, 1, 2, 2, 3};
        TopkFrequentElements topkFrequentElements = new TopkFrequentElements();
        int[] arr = topkFrequentElements.topKFrequent(nums, 2);
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}
